package com.web.kftsdk.common.api;

import com.web.kftsdk.common.bean.*;
import com.web.kftsdk.common.exception.PayErrorException;
import com.web.kftsdk.common.http.HttpConfigStorage;
import com.web.kftsdk.common.http.HttpRequestTemplate;

import java.io.InputStream;
import java.util.Map;

/**
 * 支付服务
 * @author xukk
 */
public interface PayService {
    /**
     * 设置支付配置
     * @param payConfigStorage 支付配置
     * @return 支付服务
     */
    PayService setPayConfigStorage(PayConfigStorage payConfigStorage);

    /**
     * 获取支付配置
     *
     * @return 支付配置
     */
    PayConfigStorage getPayConfigStorage();
    /**
     * 获取http请求工具
     *
     * @return http请求工具
     */
    HttpRequestTemplate getHttpRequestTemplate();

    /**
     * 设置 请求工具配置  设置并创建请求模版， 代理请求配置这里是否合理？？，
     * @param configStorage http请求配置
     * @return  支付服务
     */
    PayService setRequestTemplateConfigStorage(HttpConfigStorage configStorage);


    String sign(String content, String charset) throws PayErrorException;
    /**
     * 回调校验
     *
     * @param params 回调回来的参数集
     * @return 签名校验 true通过
     */
    boolean verify(Map<String, String> params) throws PayErrorException;

    /**
     * 获取输出消息，用户返回给支付端
     *
     * @param code 状态
     * @param message 消息
     * @return 返回输出消息
     */
    PayOutMessage getPayOutMessage(String code, String message);

    /**
     * 获取成功输出消息，用户返回给支付端
     * 主要用于拦截器中返回
     * @param payMessage 支付回调消息
     * @return 返回输出消息
     */
    PayOutMessage successPayOutMessage(PayMessage payMessage);

    /**
     * 将请求参数或者请求流转化为 Map
     *
     * @param parameterMap 请求参数
     * @param is           请求流
     * @return 获得回调的请求参数
     */
    Map<String,String> getParameter2Map(Map<String, String[]> parameterMap, InputStream is)  throws PayErrorException;

    /**
     * 将请求参数或者请求流转化为 Map

     * @return 获得回调的请求参数
     */
    Map<String,String> getParameter2Map(String str, String transactionType)  throws PayErrorException;
    /**
     * 创建订单
     *
     * @param payOrder 发起支付的订单信息
     * @return 返回支付时需要的
     */
    PayRes createOrder(PayOrder<?> payOrder);

    /**
     * 创建订单
     *
     * @param payOrder 发起支付的订单信息
     * @param callback 处理器
     * @param <T> 返回类型
     * @return 返回支付时需要的
     */
    <T>PayRes<T> createOrder(PayOrder<?> payOrder, Callback<T> callback);
    /**
     * 申请退款接口
     *
     * @param refundOrder  退款订单信息
     * @return 返回支付方申请退款后的结果
     */
    PayRes refund(RefundOrder<?> refundOrder);
    /**
     * 申请退款接口
     *
     * @param refundOrder   退款订单信息
     * @param callback 处理器
     * @param <T> 返回类型
     * @return 返回支付方申请退款后的结果
     */
    <T> PayRes<T> refund(RefundOrder<?> refundOrder, Callback<T> callback);
    /**
     * 交易关闭接口
     *
     * @param payOrder   关闭订单信息
     * @return 返回支付方交易关闭后的结果
     */
    PayRes close(PayOrder<?> payOrder);

    /**
     * 交易关闭接口
     *
     * @param payOrder   关闭订单信息
     * @param callback 处理器
     * @param <T> 返回类型
     * @return 返回支付方交易关闭后的结果
     */
    <T> PayRes<T> close(PayOrder<?> payOrder, Callback<T> callback);

    /**
     * 获取App支付信息，用户返回给支付端,
     *
     * @param payOrder 发起支付的订单信息
     * @return 返回图片信息，支付时需要的
     */
    PayRes genAppPay(PayOrder<?> payOrder);

    /**
     * 获取App支付信息，用户返回给支付端,
     *
     * @param payOrder 发起支付的订单信息
     * @param <T> 返回类型
     * @return 返回支付时需要的
     */
    <T>PayRes<T> genAppPay(PayOrder<?> payOrder, Callback<T> callback);
    /**
     * 获取输出二维码，用户返回给支付端,
     *
     * @param payOrder 发起支付的订单信息
     * @return 返回图片信息，支付时需要的
     */
    PayRes genQrPay(PayOrder<?> payOrder);

    /**
     * 获取输出二维码，用户返回给支付端,
     *
     * @param payOrder 发起支付的订单信息
     * @param <T> 返回类型
     * @return 返回支付时需要的
     */
    <T>PayRes<T> genQrPay(PayOrder<?> payOrder, Callback<T> callback);

    /**
     * 刷卡付,pos主动扫码付款(条码付)
     *
     * @param payOrder 发起支付的订单信息
     * @return 返回支付结果
     */
    PayRes  microPay(PayOrder<?> payOrder);

    /**
     * 刷卡付,pos主动扫码付款(条码付)
     *
     * @param payOrder 发起支付的订单信息
     * @param <T> 返回类型
     * @return 返回支付结果
     */
    <T>PayRes<T>  microPay(PayOrder<?> payOrder, Callback<T> callback);
    /**
     * 交易查询接口
     *
     * @param  payOrder   查询信息
     * @return 返回查询回来的结果集，支付方原值返回
     */
    PayRes query(PayOrder<?> payOrder);
    /**
     * 交易查询接口，带处理器
     * @param payOrder 发起支付的订单信息
     * @param callback 处理器
     * @param <T> 返回类型
     * @return  返回查询回来的结果集
     */
    <T>T query(PayOrder<?> payOrder, Callback<T> callback);

    /**
     * 查询退款
     *
     * @param refundOrder  查询信息
     * @return 返回支付方查询退款后的结果
     */
    PayRes refundQuery(RefundOrder<?> refundOrder);
    /**
     * 查询退款
     *
     * @param refundOrder  查询信息
     * @param callback 处理器
     * @param <T> 返回类型
     * @return 返回支付方查询退款后的结果
     */
    <T>PayRes<T> refundQuery(RefundOrder<?> refundOrder, Callback<T> callback);
    /**
     * 下载对账单
     *
     * @param billDate 账单时间：日账单格式为yyyy-MM-dd，月账单格式为yyyy-MM。
     * @param billType 账单类型，商户通过接口或商户经开放平台授权后其所属服务商通过接口可以获取以下账单类型：trade、signcustomer；trade指商户基于支付宝交易收单的业务账单；signcustomer是指基于商户支付宝余额收入及支出等资金变动的帐务账单；
     * @param params 额外参数
     * @return 返回支付方下载对账单的结果
     */
    PayRes downLoadBill(String billDate, String billType, String... params);
    /**
     * 下载对账单
     *
     * @param billDate 账单时间：具体请查看对应支付平台
     * @param billType 账单类型，具体请查看对应支付平台
     * @param callback 处理器
     * @param params 额外参数
     * @param <T> 返回类型
     * @return 返回支付方下载对账单的结果
     */
    <T>PayRes<T> downLoadBill(String billDate, String billType, Callback<T> callback, String... params);
    /**
     * 转账
     * @param transferOrder 转账订单
     * @return 对应的转账结果
     */
    PayRes transfer(TransferOrder<?> transferOrder);
    /**
     * 转账
     * @param transferOrder 转账订单
     * @param callback 处理器
     * @param <T> 返回类型
     * @return 对应的转账结果
     */
    <T>PayRes<T> transfer(TransferOrder<?> transferOrder, Callback<T> callback);
    /**
     * 转账查询
     *
     * @param transferOrder 查询信息
     * @return 对应的转账订单
     */
    PayRes transferQuery(TransferOrder<?> transferOrder);
    /**
     * 转账查询
     *
     * @param transferOrder 查询信息
     * @param callback 处理器
     * @param <T> 返回类型
     * @return 对应的转账订单
     */
    <T>PayRes<T> transferQuery(TransferOrder<?> transferOrder, Callback<T> callback);



}
